package cn.edu.swu.miniwebsvr.handler;

import cn.edu.swu.miniwebsvr.core.Handler;
import cn.edu.swu.miniwebsvr.core.Parameter;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.Map;

public class EchoHandler implements Handler {

    @Override
    public void handle(Parameter request, OutputStream response) {
        // 使用UTF-8编码的PrintWriter
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(response, StandardCharsets.UTF_8), true);

        try {
            Map<String, String> params = request.getAllParams();
            Map<String, String> urlParams = request.getUrlParams();
            Map<String, String> bodyParams = request.getBodyParams();
            Map<String, String> headers = request.getHeaders();

            // 构建完整的HTML内容
            String htmlContent = buildHtmlContent(request, params, urlParams, bodyParams, headers);
            byte[] contentBytes = htmlContent.getBytes(StandardCharsets.UTF_8);

            // 构造完整的 HTTP 响应头，明确指定UTF-8编码
            writer.println("HTTP/1.1 200 OK");
            writer.println("Content-Type: text/html; charset=UTF-8");
            writer.println("Content-Length: " + contentBytes.length);
            writer.println("Connection: close");
            writer.println("Server: MiniWebSvr/1.0");
            writer.println("Cache-Control: no-cache");
            writer.println(); // 空行分隔头部和体部

            writer.print(htmlContent);

            // 记录请求日志
            System.out.println("EchoHandler: Processed " + request.getMethod() + " request with " + params.size() + " parameters");

        } catch (Exception e) {
            // 如果发生异常，返回500错误
            System.err.println("EchoHandler error: " + e.getMessage());
            sendErrorResponse(writer, e);
        }
    }

    /**
     * 构建HTML内容
     */
    private String buildHtmlContent(Parameter request, Map<String, String> allParams,
                                    Map<String, String> urlParams, Map<String, String> bodyParams,
                                    Map<String, String> headers) {
        StringBuilder html = new StringBuilder();

        html.append("<!DOCTYPE html>");
        html.append("<html lang=\"zh-CN\">");
        html.append("<head>");
        html.append("    <meta charset=\"UTF-8\">");
        html.append("    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">");
        html.append("    <title>Echo Server - MiniWebSvr</title>");
        html.append("    <style>");
        html.append("        body {");
        html.append("            font-family: 'Microsoft YaHei', Arial, sans-serif;");
        html.append("            margin: 0;");
        html.append("            padding: 20px;");
        html.append("            background: linear-gradient(135deg, #74b9ff 0%, #0984e3 100%);");
        html.append("            min-height: 100vh;");
        html.append("        }");
        html.append("        .container {");
        html.append("            max-width: 1000px;");
        html.append("            margin: 0 auto;");
        html.append("        }");
        html.append("        .card {");
        html.append("            background: white;");
        html.append("            padding: 30px;");
        html.append("            border-radius: 15px;");
        html.append("            box-shadow: 0 10px 30px rgba(0,0,0,0.2);");
        html.append("            margin-bottom: 20px;");
        html.append("        }");
        html.append("        h1 {");
        html.append("            color: #2d3436;");
        html.append("            text-align: center;");
        html.append("            margin-bottom: 30px;");
        html.append("        }");
        html.append("        h2 {");
        html.append("            color: #0984e3;");
        html.append("            border-bottom: 2px solid #74b9ff;");
        html.append("            padding-bottom: 10px;");
        html.append("        }");
        html.append("        .request-info {");
        html.append("            display: grid;");
        html.append("            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));");
        html.append("            gap: 15px;");
        html.append("            margin-bottom: 20px;");
        html.append("        }");
        html.append("        .info-item {");
        html.append("            background: #f8f9fa;");
        html.append("            padding: 15px;");
        html.append("            border-radius: 8px;");
        html.append("            border-left: 4px solid #74b9ff;");
        html.append("        }");
        html.append("        .param-section {");
        html.append("            margin-bottom: 25px;");
        html.append("        }");
        html.append("        .param-table {");
        html.append("            width: 100%;");
        html.append("            border-collapse: collapse;");
        html.append("            margin-top: 10px;");
        html.append("        }");
        html.append("        .param-table th, .param-table td {");
        html.append("            padding: 12px 15px;");
        html.append("            text-align: left;");
        html.append("            border-bottom: 1px solid #ddd;");
        html.append("        }");
        html.append("        .param-table th {");
        html.append("            background: #74b9ff;");
        html.append("            color: white;");
        html.append("        }");
        html.append("        .param-table tr:hover {");
        html.append("            background: #f8f9fa;");
        html.append("        }");
        html.append("        .empty-message {");
        html.append("            text-align: center;");
        html.append("            color: #636e72;");
        html.append("            font-style: italic;");
        html.append("            padding: 20px;");
        html.append("        }");
        html.append("        .badge {");
        html.append("            display: inline-block;");
        html.append("            padding: 4px 8px;");
        html.append("            background: #00b894;");
        html.append("            color: white;");
        html.append("            border-radius: 12px;");
        html.append("            font-size: 0.8em;");
        html.append("            margin-left: 8px;");
        html.append("        }");
        html.append("    </style>");
        html.append("</head>");
        html.append("<body>");
        html.append("    <div class=\"container\">");
        html.append("        <div class=\"card\">");
        html.append("            <h1>📨 Echo Server Response</h1>");
        html.append("            ");
        html.append("            <div class=\"request-info\">");
        html.append("                <div class=\"info-item\">");
        html.append("                    <strong>Request Method:</strong><br>").append(escapeHtml(request.getMethod()));
        html.append("                </div>");
        html.append("                <div class=\"info-item\">");
        html.append("                    <strong>Request Path:</strong><br>").append(escapeHtml(request.getUrl()));
        html.append("                </div>");
        html.append("                <div class=\"info-item\">");
        html.append("                    <strong>Total Parameters:</strong><br>");
        html.append("                    ").append(allParams.size()).append(" parameters");
        html.append("                </div>");
        html.append("            </div>");
        html.append("            ");
        html.append("            <div class=\"param-section\">");
        html.append("                <h2>All Parameters ").append("<span class=\"badge\">").append(allParams.size()).append("</span></h2>");
        if (allParams.isEmpty()) {
            html.append("                <div class=\"empty-message\">No parameters received</div>");
        } else {
            html.append("                <table class=\"param-table\">");
            html.append("                    <thead>");
            html.append("                        <tr><th>Parameter Name</th><th>Parameter Value</th></tr>");
            html.append("                    </thead>");
            html.append("                    <tbody>");
            for (Map.Entry<String, String> entry : allParams.entrySet()) {
                html.append("                    <tr>");
                html.append("                        <td><strong>").append(escapeHtml(entry.getKey())).append("</strong></td>");
                html.append("                        <td>").append(escapeHtml(entry.getValue())).append("</td>");
                html.append("                    </tr>");
            }
            html.append("                    </tbody>");
            html.append("                </table>");
        }
        html.append("            </div>");
        html.append("            ");
        html.append("            <div class=\"param-section\">");
        html.append("                <h2>URL Parameters ").append("<span class=\"badge\">").append(urlParams.size()).append("</span></h2>");
        if (urlParams.isEmpty()) {
            html.append("                <div class=\"empty-message\">No URL parameters</div>");
        } else {
            html.append("                <table class=\"param-table\">");
            html.append("                    <thead>");
            html.append("                        <tr><th>Parameter Name</th><th>Parameter Value</th></tr>");
            html.append("                    </thead>");
            html.append("                    <tbody>");
            for (Map.Entry<String, String> entry : urlParams.entrySet()) {
                html.append("                    <tr>");
                html.append("                        <td><strong>").append(escapeHtml(entry.getKey())).append("</strong></td>");
                html.append("                        <td>").append(escapeHtml(entry.getValue())).append("</td>");
                html.append("                    </tr>");
            }
            html.append("                    </tbody>");
            html.append("                </table>");
        }
        html.append("            </div>");
        html.append("            ");
        html.append("            <div class=\"param-section\">");
        html.append("                <h2>Body Parameters ").append("<span class=\"badge\">").append(bodyParams.size()).append("</span></h2>");
        if (bodyParams.isEmpty()) {
            html.append("                <div class=\"empty-message\">No body parameters</div>");
        } else {
            html.append("                <table class=\"param-table\">");
            html.append("                    <thead>");
            html.append("                        <tr><th>Parameter Name</th><th>Parameter Value</th></tr>");
            html.append("                    </thead>");
            html.append("                    <tbody>");
            for (Map.Entry<String, String> entry : bodyParams.entrySet()) {
                html.append("                    <tr>");
                html.append("                        <td><strong>").append(escapeHtml(entry.getKey())).append("</strong></td>");
                html.append("                        <td>").append(escapeHtml(entry.getValue())).append("</td>");
                html.append("                    </tr>");
            }
            html.append("                    </tbody>");
            html.append("                </table>");
        }
        html.append("            </div>");
        html.append("            ");
        html.append("            <div class=\"param-section\">");
        html.append("                <h2>Request Headers ").append("<span class=\"badge\">").append(headers.size()).append("</span></h2>");
        if (headers.isEmpty()) {
            html.append("                <div class=\"empty-message\">No request headers</div>");
        } else {
            html.append("                <table class=\"param-table\">");
            html.append("                    <thead>");
            html.append("                        <tr><th>Header Name</th><th>Header Value</th></tr>");
            html.append("                    </thead>");
            html.append("                    <tbody>");
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                html.append("                    <tr>");
                html.append("                        <td><strong>").append(escapeHtml(entry.getKey())).append("</strong></td>");
                html.append("                        <td>").append(escapeHtml(entry.getValue())).append("</td>");
                html.append("                    </tr>");
            }
            html.append("                    </tbody>");
            html.append("                </table>");
        }
        html.append("            </div>");
        html.append("        </div>");
        html.append("    </div>");
        html.append("</body>");
        html.append("</html>");

        return html.toString();
    }

    /**
     * HTML转义，防止XSS攻击
     */
    private String escapeHtml(String text) {
        if (text == null) return "";
        return text.replace("&", "&amp;")
                .replace("<", "&lt;")
                .replace(">", "&gt;")
                .replace("\"", "&quot;")
                .replace("'", "&#39;");
    }

    /**
     * 发送错误响应
     */
    private void sendErrorResponse(PrintWriter writer, Exception e) {
        try {
            String errorHtml = "<!DOCTYPE html>" +
                    "<html><head><meta charset=\"UTF-8\"><title>500 Error</title></head>" +
                    "<body><h1>500 Internal Server Error</h1>" +
                    "<p>EchoHandler error: " + escapeHtml(e.getMessage()) + "</p>" +
                    "</body></html>";

            byte[] contentBytes = errorHtml.getBytes(StandardCharsets.UTF_8);

            writer.println("HTTP/1.1 500 Internal Server Error");
            writer.println("Content-Type: text/html; charset=UTF-8");
            writer.println("Content-Length: " + contentBytes.length);
            writer.println("Connection: close");
            writer.println();
            writer.print(errorHtml);
            writer.flush();
        } catch (Exception ex) {
            // 忽略错误响应发送失败的情况
        }
    }
}